﻿using System;
using System.Collections.Generic;
using System.Text;

namespace JESAI.Common.Util.Threating.Locking
{
    /// <summary>
    /// 使锁定更容易的扩展方法。
    /// </summary>
    public static class LockExtensions
    {
        /// <summary>
        /// 通过锁定给定的<see cref="source"/>对象来执行给定的<see cref="action"/>
        /// </summary>
        /// <param name="source">源对象（要锁定）</param>
        /// <param name="action">Action（待执行）</param>
        public static void Locking(this object source, Action action)
        {
            lock (source)
            {
                action();
            }
        }
        /// <summary>
        /// 通过锁定给定的<see cref="source"/>对象来执行给定的<see cref="action"/>
        /// </summary>
        /// <typeparam name="T">对象的类型（要锁定）</typeparam>
        /// <param name="source">源对象（要锁定）</param>
        /// <param name="action">Action（待执行）</param>
        public static void Locking<T>(this T source, Action<T> action) where T : class
        {
            lock (source)
            {
                action(source);
            }
        }
        /// <summary>
        /// 执行给定的<paramref name="func"/>并通过锁定给定的<paramref name="source"/>对象返回其值。
        /// </summary>
        /// <typeparam name="TResult">返回类型</typeparam>
        /// <param name="source">源对象（要锁定）</param>
        /// <param name="func">func(将被执行)</param>
        /// <returns></returns>
        public static TResult Locking<TResult>(this object source, Func<TResult> func)
        {
            lock (source)
            {
                return func();
            }
        }
        /// <summary>
        /// 执行给定的<paramref name="func"/>并通过锁定给定的<paramref name="source"/>对象返回其值。
        /// </summary>
        /// <typeparam name="T">对象的类型（要锁定）</typeparam>
        /// <typeparam name="TResult">返回类型</typeparam>
        /// <param name="source">源对象（要锁定）</param>
        /// <param name="func">func(将被执行)</param>
        /// <returns></returns>
        public static TResult Locking<T, TResult>(this T source, Func<T, TResult> func) where T : class
        {
            lock (source)
            {
                return func(source);
            }
        }
    }
}
